from pattern.circuit import Control
from algonquin.circuit import CircuitGeometry


class InnerCircuit(object):

    def __init__(self, parent_circuit, container_shape):
        self.parent = parent_circuit
        self.shape = container_shape
        
    def __getattr__(self, nm):
        return getattr(self.parent, nm)
        
    def emit(self, e4shape, cb, **kwargs):
        # Impersonate!
        self.parent.emit.im_func(self, e4shape, cb, **kwargs)
        
    def call(self, e4shape, cb, fallback=None, **kwargs):
        # Impersonate!
        self.parent.call.im_func(self, e4shape, cb, fallback, **kwargs)
        
    def get_container(self, shape):
        container = self.parent.get_container(shape)
            
        if container is self.shape:
            return None
        else:
            return container


class entry(Control):

    VERBS = ["Arrange", "Conjure"]

    InnerCircuit = InnerCircuit
    
    def realize(self, event):
        self.inner_circuit = self.InnerCircuit(event.window, event.shape)

    def incoming(self, event):
        for bridge in self.acquireSubcomponents(event):
            bridge.push(*event.data)
            
    def verb(self, event):
        if event.verb == "Arrange":
            self.arrange(event)
        elif event.verb == "Conjure":
            self.conjure(event)
            
    def emit(self, event):
        if event.window is not self.inner_circuit:
            print "Emitting", event.slot, event.kwargs
        self.inner_circuit.call(event.for_shape, event.slot, **event.kwargs)
        
    def arrange(self, event):
        corner = self.acquireOutlet(event, "corner")
        x, y = corner.at()
        i = 0
        for bridge in self.acquireSubcomponents(event):
            shape = bridge.connector.points()[1].shape()
            event.window.manipulate(shape, \
                lambda sp: sp.moveto(x+10, y+10+25*i))
            i += 1

    def conjure(self, event):
        corner = self.acquireOutlet(event, "corner")
        x, y = corner.at()
        newshape = event.window.Rectangle(x+90, y+90, 15, 15, origin=corner)
        event.window.manipulate(event.shape, \
            lambda sp: event.window.shapes.append(newshape))
